创作类《塞尔达传说:旷野之息》风格的水着色器
《塞尔达传说:旷野之息》是任天堂游戏公司出版发行的开放世界动作冒险游戏。发售以来获得业界极高评价,2017年获金摇杆奖年度最佳游戏奖,TGA 2017年度最佳游戏。
来自德国柏林22岁的Florian Gelzenleuchter也是这款游戏的忠实粉丝,他正在独立制作一个项目《The Bells' Arietta》,这个项目将使用Unity实现《塞尔达传说:旷野之息》的画面表现效果。
下面是《The Bells' Arietta》的演示视频。
项目介绍
有没有觉得《The Bells' Arietta》中画面效果和《塞尔达传说:旷野之息》相差无几呢?
本文,我们将重点介绍《The Bells' Arietta》中,制作水着色器的工作流程。下面是《The Bells' Arietta》中水着色器的效果。
在收集参考素材时,我会仔细观察现实中的效果,以及效果在游戏内的实现结果。这不仅有助于给予启发,而且也提供了实用的信息,告诉我可以实现什么东西,以及什么地方可能出现问题。
如果有人问我:在《塞尔达传说:旷野之息》中,什么东西会在神庙内提供独特的感觉?
我会把答案总结为三个重要部分:冰冷而美观的大理石、穿过空气的光束、以及清澈透明的水。认真思考后,我开始制作水着色器。
项目机制
由于游戏角色林克无法潜入水底,所以《塞尔达传说:旷野之息》的水会让玩家的摄像机一直保持在水面上。
在水体内渲染水效果时,通常需要复杂的着色器设置和额外的水下效果。而且,把摄像机限制在水面可以简化摄像机的移动。
我设定了相同的限制,这样便可以专注于从水面上观察水的外观,也让我可以使用着色器技巧,例如:为水下的雾效果使用深度缓冲区。
实现焦散效果
在光线被弯曲表面折射,然后投射到水底时,便会出现焦散效果中令人着迷的图案。常见的焦散效果例子是一杯水或游泳池表面被阳光照射时的画面。
下图是大海中的焦散效果。
首先,我们要解决的问题是焦散效果的动画。类似其它能量类效果,焦散效果有非常自然的外观。对于噪声部分,常用的方法是在Photoshop中使用简单的混合设置来制作原型。
在本示例中,我们可以注意到下图左侧的基本纹理。我为纹理的每个通道加入了少量偏移,用于计算光线折射。然后创建图层副本,把图案放大,然后把混合模式改为Darken变暗。
移动图层副本时,便会出现混合后的特别效果。在最后的图案中,通过附加方式把纹理混合到沙滩纹理上。在最终着色器中,两个图层会独立移动。
现在,我可以把结果从光线方向投射到对象上。通过使用NdotL和对象的阴影贴图加入额外遮罩,现在焦散效果几乎完成了。
后续步骤取决于对象本身,通常情况下会有一个高度值,该值会在对象所在水面的高度上划分效果。如果资源是小型模块化资源,该值会在多数情况下起到作用。
但是,如果连接的地形有不同高度,我们则无法定义通用的Cutoff值。使用深度缓冲区是一种解决方法,但在渲染透明对象前,我们无法获取该对象的深度。由于我们必须计算每个对象的焦散效果和着色器,因此整个效果的性能不是很好。
项目中,我使用的解决方法利用了游戏引擎中透明对象的特点。这类对象不会渲染到深度缓冲区或G缓冲区,因此我可以访问所有水下对象的法线和深度信息。
深度信息用于计算世界位置,这种方法通常用于后期处理效果。通过使用这种方法,所有工作都可以在一个着色器内完成,焦散效果会自动影响写入深度缓冲区的所有内容。
纹理制作
水着色器由多个部分组成。它利用了一个经典方法:让两个法线贴图以不同速度和大小互相重叠滚动,这样就可以轻松调整表面的外观。
这个方法也适用于焦散纹理和另一个噪声纹理,用来实现水泡等更多细节。由于使用平面映射,在水流到达特定角度时,水的流速也会变快,因此我可以把该着色器放到任何位置,使水的流动效果接近现实。
水着色器的功能如下:
带有法线贴图的表面细节。
在角度较大的位置,流速会变快。
焦散效果会从阳光方向投射到表面下的所有内容。
基于深度的折射效果,因此在浅水区的折射效果较小。
水面上的水泡和阴影。
水下的雾、模糊和色差效果。
通过顶点颜色定义位移效果区。
使用Unity的挑战
在实现逼真的水着色器时,平衡美感和交互性是关键。无论现实与否,水都应该看起来富有活力,这就是为什么即使是《塞尔达传说:风之杖》的单色海洋也会使人感到逼真的原因。
使用顶点替换和滚动两个法线贴图的方法是一个很好的起点,我们还会加入一些折射效果,使用基本的水着色器做进一步优化。
另一个重要部分是交互性,例如:游泳时角色会产生波浪,碰撞时会溅起水花,岸边的沙子碰到水浪时会变湿。
将水加入游戏世界时,我们要让它和所有内容融合起来,而不是类似互相独立的物体。当然,这也很大程度上取决于游戏的特定需求。
如果想要知道自己的水着色器效果如何,我们可以询问别人是否想在这片虚拟的像素流体中游泳。如果对方回答是的话,这将是很积极的评价。
关于处理着色器的建议
在处理着色器时,必须清楚自己想要实现的效果,并根据游戏机制来进行开发。着色器是很好的工具,可以把游戏过程和游戏世界融合起来。对于着色器初学者,建议建立自己的工具库,从而制作出色的效果。
我总会尝试实现想法中的新功能,即使可能不会在任何项目中使用这些功能。但如果现在花时间研究看似不实用的东西,它可能在未来会成为其它项目的重要部分。
虽然我们经常会使用新方法,但也别忘了经典的方法或更简单的方法。在游戏开发中,很多东西会发生变化,结合使用基本方法实现复杂的效果是一件很有趣的事。
如果你总是追寻最新方法,却忽视了过去的方法,这样可能会浪费潜在的优秀工具。我们应该充分利用新方法和旧方法的潜力,为我们的工作提供便利。
小结
对于着色器编程而言,水效果是很好的实现目标。目前有很多出色的效果案例,而且新的创意和艺术风格仍在不断给人惊喜,精美的水效果从不会过时,所以赶紧实践去完成精美的水效果吧。
下载Unity Connect APP,请点击此处。 观看更多Unity官方精彩视频,请关注“Unity官方”B站账户。
你可以访问Unity答疑专区留下你的问题,Unity社区和官方团队帮你解答:
Connect.unity.com/g/discussion
推荐阅读
使用Shader Graph实现《塞尔达传说:旷野之息》风格的着色器
2020年Unity Pro专业版和Plus加强版订阅价格将调整
喜欢本文,请点击“在看”